Análisis Inicial vs Exploratorio de Datos

R para Ciencia de Datos en Salud:
Análisis Descriptivo e Inferencia Estadística

Percy Soto-Becerra M.D., M.Sc(c)

InkaStats Data Science Solutions | Medical Branch
@github/psotob91

Análisis Exploratorio de Datos versus Análisis Inicial de Datos



El análisis inicial de datos y el análisis exploratorio de datos son dos cosas diferentes!!

Análisis Exploratorio de Datos


Análisis Exploratorio de Datos

  • El AED es un enfoque de análisis de conjunto de datos para identificar patrones y formular nuevas hipótesis.

  • Se trata de ver qué nos dice los datos más allá de ideas pre-concebidas.

  • Las nuevas hipótesis luego se confirman en otros nuevos estudios rigurosos.

  • Su versión moderna: Minería de Datos (Data Minning)

Análisis Inicial de Datos

  • El AID, a menudo, se confunde erróneamente con el AED:

    • Ambos son dos enfoques totalmente diferentes que comparten herramietnas comunes.
  • Objetivo del AID:

“(…) garantizar principalmente la transparencia y la integridad de las condiciones previas para realizar análisis estadísticos apropiados de manera responsable para responder preguntas de investigación predefinidas.”
Baillie M, et al. [PLoS Comput Biol, 2022]
(https://doi.org/10.1371/journal.pcbi.1009819)

Análisis Inicial de Datos vs. Análisis Exploratorio de Datos


AID AED
1. AID es el paso inicial del proceso de confirmación de hipótesis pre-definidas. 1. AED busca generar hipótesis nuevas.
2. En investigación clínico-epidemiológica, a menudo queremos y deberíamos hacer AID. 2. Rara vez queremos AED (p. ej., enfermedades nuevas, fenómenos muy poco conocidos)
3. Proceso clave para garantizar responder adecuadamente objetivos pre-planeados de estudio. 3. Proceso con alto riesgo de contaminar respuesta a objetivos pre-planeados de estudio.

Mala práctica: ¡Hacer AED en vez de AID!


  • A menudo, investigadores no realizan AID de manera sistemática.
  • Mezclan actividades de AID con tareas posteriores de análisis de datos, como generación o exploración de hipótesis, análisis formal e interpretación de conclusiones.
  • Como se hacen “informalmente”, no se reportan en detalle generándose análisis ocultos.

Mala práctica: ¡Hacer AED en vez de AID! (cont.)

  • Estos análisis ocultos generan problemas en la reproducibilidad de los estudios.
  • Generan muchos grados de libertad adicionales ocasionando problemas serios de validez de los análisis: p-hacking, post-selection inference, double-dipping, overfitting, etc.
  • Iniciativa STRATOS ha dado pautas para realizar AID apropiados.

El problema de los análisis ocultos

BMC Med Res Methodol 20, 61 (2020)

Recomendaciones de STRATOS para hacer un buen AID

PLoS Comput Biol 18(2): e1009819

AID es un proceso iterativo

  • Proceso no lineal, al contrario, requiere muchas iteraciones.

  • Riesgo: Puede influir en análisis e inducir conclusiones erróneas.

    • Mayor riesgo de restultados falsos positivos.
  • Ser cuidados para:

    • Evitar alterar la pregunta de investigación.
    • Proveer documentación completa del proceso.

AID como parte del plan de investigación

Introducing the Initial Data Analysis Topic Group (TG3)

AID como parte del plan de investigación

Huebner M, Vach W, et al.

10 recomendaciones de STRATOS para un buen AID

  • Regla 1: Desarrolle un plan de AID que respalde el objetivo de la investigación.

  • Regla 2: AID toma tiempo y recursos.

  • Regla 3: AID debe ser reproducible.

  • Regla 4: El contexto importa, conoce tus datos.

  • Regla 5: Evite los adelantos, AID no toca la pregunta de investigación.

10 recomendaciones de STRATOS para un buen AID (cont.)

  • Regla 6: Visualiza tus datos.

  • Regla 7: Compruebe lo que falte.

  • Regla 8: Comunicar los hallazgos y considerar las consecuencias.

  • Regla 9: Reporte los hallazgos del AID en trabajos de investigación (¡adjunte anexos!)

  • Regla 10: Sea proactivo y riguroso.

Análisis Inicial de Datos con R

Análisis Inicial de Datos con R

Regla 3: El contexto importa, conoce tus datos

  • Dé una primera mirada global a los datos
  • Diseñe una lista de validaciones a realizar desde el proyecto.
  • Valida tus datos:
    • Identifique duplicados y detecte inconsistencias
    • Valores extremos no plausibles
    • Identifique valores perdidos
  • En R, use los 5 verbos básicos de {dplyr}: filter(), select(), mutate(), arrange() y summarise() para hacer consultas ("queries") a sus datos.

Regla 3 con R: Resumen global de los datos

glimpse(datos)
Rows: 26
Columns: 13
$ id_jaula     <dbl> 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 5, 5, 5, 5, 8, 8, 9, 9, 9, …
$ id_raton     <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17…
$ tratamiento  <chr> "control", "control", "control", "control", "control", "m…
$ protocolo    <chr> "ovx", "ovx", "ovx", "hemiovx", "ovx", "ovx", "ovx", "ovx…
$ peso_inicial <dbl> 26.00, 24.50, 20.40, 26.59, 23.50, 25.00, 24.80, 23.20, 2…
$ peso_final   <dbl> 33.28, 30.50, 29.93, 32.19, 30.37, 30.43, 28.77, 27.30, 2…
$ peso_utero   <dbl> 0.089, 0.063, 0.078, 0.134, 0.052, 0.055, 0.064, 0.062, 0…
$ chol         <dbl> 85.990, 94.460, 99.670, 83.380, 82.080, 107.490, 76.870, …
$ glucose      <dbl> 109.97, 81.62, 118.37, 71.91, 95.53, 160.36, 195.53, 182.…
$ tag          <dbl> 182.42, 211.87, 195.16, 98.46, 108.13, 141.10, 95.82, 105…
$ prot         <dbl> 5.37, 4.68, NA, NA, 5.33, NA, 5.02, 6.12, NA, 4.85, NA, N…
$ urea         <dbl> 66.27, 76.73, 52.32, 50.71, 26.02, NA, 40.78, 66.94, NA, …
$ album        <dbl> 66.82, 55.36, NA, NA, NA, 72.14, 67.09, 70.64, 66.27, 83.…
  • También de Hmisc:
contents(datos)

Data frame:datos    26 observations and 13 variables    Maximum # NAs:13

               Storage NAs
id_jaula        double   0
id_raton        double   0
tratamiento  character   0
protocolo    character   0
peso_inicial    double   0
peso_final      double   0
peso_utero      double   0
chol            double   0
glucose         double   0
tag             double   0
prot            double  12
urea            double  10
album           double  13
html(contents(datos), levelType = 'table')
datos Contents

Data frame:datos

26 observations and 13 variables, maximum # NAs:13  
NameStorageNAs
id_jauladouble 0
id_ratondouble 0
tratamientocharacter 0
protocolocharacter 0
peso_inicialdouble 0
peso_finaldouble 0
peso_uterodouble 0
choldouble 0
glucosedouble 0
tagdouble 0
protdouble12
ureadouble10
albumdouble13

Regla 3 con R: Detecte duplicados

  • Función get_dupes del paquete {janitor}.
  • Si solo colocamos get_dupes(), entonces nos identifica duplicados de fila completa:
library(janitor)
datos %>% 
  get_dupes()
  id_jaula id_raton tratamiento protocolo peso_inicial peso_final peso_utero
1        1        1     control       ovx        26.00      33.28      0.089
2        1        1     control       ovx        26.00      33.28      0.089
3        2        5     control       ovx        23.50      30.37      0.052
4        2        5     control       ovx        23.50      30.37      0.052
5        3        9        maca   hemiovx        22.69      26.86      0.070
6        3        9        maca   hemiovx        22.69      26.86      0.070
   chol glucose    tag prot  urea album dupe_count
1 85.99  109.97 182.42 5.37 66.27 66.82          2
2 85.99  109.97 182.42 5.37 66.27 66.82          2
3 82.08   95.53 108.13 5.33 26.02    NA          2
4 82.08   95.53 108.13 5.33 26.02    NA          2
5 85.34  184.51  90.99   NA    NA 66.27          2
6 85.34  184.51  90.99   NA    NA 66.27          2
  • Si colocamos una o más variables dentro de get_dupes(), entonces nos identifica duplicados solo de esa variable.

  • A menudo lo hacemos para encontrar individus duplicados.

datos %>% 
  get_dupes(id_raton)
  id_raton dupe_count id_jaula tratamiento protocolo peso_inicial peso_final
1        1          2        1     control       ovx        26.00      33.28
2        1          2        1     control       ovx        26.00      33.28
3        5          2        2     control       ovx        23.50      30.37
4        5          2        2     control       ovx        23.50      30.37
5        9          2        3        maca   hemiovx        22.69      26.86
6        9          2        3        maca   hemiovx        22.69      26.86
  peso_utero  chol glucose    tag prot  urea album
1      0.089 85.99  109.97 182.42 5.37 66.27 66.82
2      0.089 85.99  109.97 182.42 5.37 66.27 66.82
3      0.052 82.08   95.53 108.13 5.33 26.02    NA
4      0.052 82.08   95.53 108.13 5.33 26.02    NA
5      0.070 85.34  184.51  90.99   NA    NA 66.27
6      0.070 85.34  184.51  90.99   NA    NA 66.27
  • Si el duplicado es erróneo, lo podemos eliminar con distinct y el argumento .keep_all = TRUE.

  • Se debde espeficiar si el duplicado es de fila o de alguna variable (p. ej., id).

datos <- datos %>% 
  distinct(id_raton, .keep_all = TRUE)

datos
   id_jaula id_raton               tratamiento protocolo peso_inicial
1         1        1                   control       ovx        26.00
2         1        2                   control       ovx        24.50
3         1        3                   control       ovx        20.40
4         2        4                   control   hemiovx        26.59
5         2        5                   control       ovx        23.50
6         2        6                      maca       ovx        25.00
7         2        7                      maca       ovx        24.80
8         3        8                      maca       ovx        23.20
9         3        9                      maca   hemiovx        22.69
10        3       10                      maca       ovx        23.90
11        5       11             maca + critro       ovx        21.90
12        5       12             maca + critro       ovx        23.40
13        5       13             maca + critro       ovx        21.90
14        5       14             maca + critro       ovx        22.40
15        8       15 triple dosis maca + citro       ovx        18.90
16        8       16 triple dosis maca + citro       ovx        23.50
17        9       17 triple dosis maca + citro       ovx        24.50
18        9       18 triple dosis maca + citro       ovx        25.30
19        9       19 triple dosis maca + citro       ovx        27.90
20        9       20             sham operated    no ovx        25.50
21       10       21             sham operated    no ovx        23.40
22       10       22             sham operated    no ovx        22.50
23       10       23             sham operated    no ovx        22.90
   peso_final peso_utero    chol glucose    tag prot   urea album
1       33.28      0.089  85.990  109.97 182.42 5.37  66.27 66.82
2       30.50      0.063  94.460   81.62 211.87 4.68  76.73 55.36
3       29.93      0.078  99.670  118.37 195.16   NA  52.32    NA
4       32.19      0.134  83.380   71.91  98.46   NA  50.71    NA
5       30.37      0.052  82.080   95.53 108.13 5.33  26.02    NA
6       30.43      0.055 107.490  160.36 141.10   NA     NA 72.14
7       28.77      0.064  76.870  195.53  95.82 5.02  40.78 67.09
8       27.30      0.062  95.760  182.41 105.49 6.12  66.94 70.64
9       26.86      0.070  85.340  184.51  90.99   NA     NA 66.27
10      29.10      0.113  82.080  168.50 143.30 4.85  34.48 83.73
11      24.93      0.108  80.781  113.38 128.35   NA     NA    NA
12      26.70      0.022  88.590  102.62 282.64   NA     NA    NA
13      28.67      0.014 104.880   60.10 200.00 5.33  37.96    NA
14      28.37      0.046  70.350  150.13 199.12 4.93  45.61 64.64
15      23.80      0.057  78.170  110.50 114.73 4.78  38.23 52.77
16      26.70      0.065  85.340  144.88 134.51 5.15  43.06 59.59
17      28.77      0.016  64.400  138.85 160.44   NA     NA    NA
18      29.20      0.068  67.100  140.68 127.03   NA     NA    NA
19      29.48      0.076  65.790  114.70 169.67 6.17     NA    NA
20      30.27      0.088  74.260   94.23 185.05 4.93     NA 68.59
21      27.90      0.535  59.280  126.77 244.84   NA  60.37    NA
22      26.68      0.081  68.400   78.22  93.19   NA 157.89    NA
23      27.43      0.176  84.690  125.20 108.13   NA     NA    NA

Regla 3 con R: Identifique valores extremos no plausibles

  • Función de paquete {skimr}:

    1)  `install.packages("skimr)`
    
    2)  `library(skimr)`
  • Revise, variable por variable valores extremos no plausibles o plausibles, pero sospechosamente extremos. El valor mínimo es p0 y el valor máximo es p100. Deben ser plausibles.

skim(datos)
Data summary
Name datos
Number of rows 23
Number of columns 13
_______________________
Column type frequency:
character 2
numeric 11
________________________
Group variables None

Variable type: character

skim_variable n_missing complete_rate min max empty n_unique whitespace
tratamiento 0 1 4 25 0 5 0
protocolo 0 1 3 7 0 3 0

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
id_jaula 0 1.00 5.30 3.38 1.00 2.00 5.00 9.00 10.00 ▇▃▅▂▇
id_raton 0 1.00 12.00 6.78 1.00 6.50 12.00 17.50 23.00 ▇▆▇▆▇
peso_inicial 0 1.00 23.68 1.99 18.90 22.59 23.50 24.90 27.90 ▂▃▇▇▂
peso_final 0 1.00 28.59 2.18 23.80 27.08 28.77 30.10 33.28 ▂▆▇▅▂
peso_utero 0 1.00 0.09 0.10 0.01 0.06 0.07 0.09 0.54 ▇▁▁▁▁
chol 0 1.00 81.96 12.89 59.28 72.31 82.08 87.29 107.49 ▅▃▇▃▃
glucose 0 1.00 124.74 37.27 60.10 99.08 118.37 147.50 195.53 ▅▇▇▃▅
tag 0 1.00 153.06 52.36 90.99 108.13 141.10 190.11 282.64 ▇▃▅▁▂
prot 11 0.52 5.22 0.49 4.68 4.91 5.08 5.34 6.17 ▇▃▅▁▃
urea 9 0.61 56.95 32.34 26.02 38.87 48.16 64.80 157.89 ▇▃▁▁▁
album 12 0.48 66.15 8.44 52.77 62.12 66.82 69.62 83.73 ▃▃▇▂▂
  • Función de paquete {Hmisc}:

    1)  `install.packages("Hmisc")`
    
    2)  `library(Hmisc)`
  • Permite hacer algo similar

describe(datos)
datos 

 13  Variables      23  Observations
--------------------------------------------------------------------------------
id_jaula 
       n  missing distinct     Info     Mean      Gmd 
      23        0        7    0.979    5.304    3.881 

lowest :  1  2  3  5  8, highest:  3  5  8  9 10
                                                    
Value          1     2     3     5     8     9    10
Frequency      3     4     3     4     2     4     3
Proportion 0.130 0.174 0.130 0.174 0.087 0.174 0.130
--------------------------------------------------------------------------------
id_raton 
       n  missing distinct     Info     Mean      Gmd      .05      .10 
      23        0       23        1       12        8      2.1      3.2 
     .25      .50      .75      .90      .95 
     6.5     12.0     17.5     20.8     21.9 

lowest :  1  2  3  4  5, highest: 19 20 21 22 23
--------------------------------------------------------------------------------
tratamiento 
       n  missing distinct 
      23        0        5 

lowest : control                   maca                      maca + critro             sham operated             triple dosis maca + citro
highest: control                   maca                      maca + critro             sham operated             triple dosis maca + citro

control (5, 0.217), maca (5, 0.217), maca + critro (4, 0.174), sham operated
(4, 0.174), triple dosis maca + citro (5, 0.217)
--------------------------------------------------------------------------------
protocolo 
       n  missing distinct 
      23        0        3 
                                  
Value      hemiovx  no ovx     ovx
Frequency        2       4      17
Proportion   0.087   0.174   0.739
--------------------------------------------------------------------------------
peso_inicial 
       n  missing distinct     Info     Mean      Gmd      .05      .10 
      23        0       19    0.998    23.68    2.244    20.55    21.90 
     .25      .50      .75      .90      .95 
   22.59    23.50    24.90    25.90    26.53 

lowest : 18.90 20.40 21.90 22.40 22.50, highest: 25.30 25.50 26.00 26.59 27.90
                                                                            
Value      18.90 20.40 21.90 22.40 22.50 22.69 22.90 23.20 23.40 23.50 23.90
Frequency      1     1     2     1     1     1     1     1     2     2     1
Proportion 0.043 0.043 0.087 0.043 0.043 0.043 0.043 0.043 0.087 0.087 0.043
                                                          
Value      24.50 24.80 25.00 25.30 25.50 26.00 26.59 27.90
Frequency      2     1     1     1     1     1     1     1
Proportion 0.087 0.043 0.043 0.043 0.043 0.043 0.043 0.043
--------------------------------------------------------------------------------
peso_final 
       n  missing distinct     Info     Mean      Gmd      .05      .10 
      23        0       21    0.999    28.59    2.483    25.11    26.68 
     .25      .50      .75      .90      .95 
   27.08    28.77    30.10    30.49    32.02 

lowest : 23.80 24.93 26.68 26.70 26.86, highest: 30.37 30.43 30.50 32.19 33.28
--------------------------------------------------------------------------------
peso_utero 
       n  missing distinct     Info     Mean      Gmd      .05      .10 
      23        0       23        1   0.0927  0.07728   0.0166   0.0268 
     .25      .50      .75      .90      .95 
  0.0560   0.0680   0.0885   0.1298   0.1718 

lowest : 0.014 0.016 0.022 0.046 0.052, highest: 0.108 0.113 0.134 0.176 0.535
--------------------------------------------------------------------------------
chol 
       n  missing distinct     Info     Mean      Gmd      .05      .10 
      23        0       21    0.999    81.96     14.9    64.54    66.05 
     .25      .50      .75      .90      .95 
   72.31    82.08    87.29    98.89   104.36 

lowest :  59.28  64.40  65.79  67.10  68.40, highest:  94.46  95.76  99.67 104.88 107.49
--------------------------------------------------------------------------------
glucose 
       n  missing distinct     Info     Mean      Gmd      .05      .10 
      23        0       23        1    124.7    43.44    72.54    78.90 
     .25      .50      .75      .90      .95 
   99.08   118.37   147.50   179.63   184.30 

lowest :  60.10  71.91  78.22  81.62  94.23, highest: 160.36 168.50 182.41 184.51 195.53
--------------------------------------------------------------------------------
tag 
       n  missing distinct     Info     Mean      Gmd      .05      .10 
      23        0       22        1    153.1    59.41    93.45    96.35 
     .25      .50      .75      .90      .95 
  108.13   141.10   190.11   209.50   241.54 

lowest :  90.99  93.19  95.82  98.46 105.49, highest: 199.12 200.00 211.87 244.84 282.64
--------------------------------------------------------------------------------
prot 
       n  missing distinct     Info     Mean      Gmd      .05      .10 
      12       11       10    0.993    5.222   0.5367    4.735    4.787 
     .25      .50      .75      .90      .95 
   4.910    5.085    5.340    6.045    6.143 

lowest : 4.68 4.78 4.85 4.93 5.02, highest: 5.15 5.33 5.37 6.12 6.17
                                                                      
Value       4.68  4.78  4.85  4.93  5.02  5.15  5.33  5.37  6.12  6.17
Frequency      1     1     1     2     1     1     2     1     1     1
Proportion 0.083 0.083 0.083 0.167 0.083 0.083 0.167 0.083 0.083 0.083
--------------------------------------------------------------------------------
urea 
       n  missing distinct     Info     Mean      Gmd      .05      .10 
      14        9       14        1    56.95    30.41    31.52    35.52 
     .25      .50      .75      .90      .95 
   38.87    48.16    64.80    73.79   105.14 

lowest :  26.02  34.48  37.96  38.23  40.78, highest:  60.37  66.27  66.94  76.73 157.89
                                                                         
Value       26.02  34.48  37.96  38.23  40.78  43.06  45.61  50.71  52.32
Frequency       1      1      1      1      1      1      1      1      1
Proportion  0.071  0.071  0.071  0.071  0.071  0.071  0.071  0.071  0.071
                                             
Value       60.37  66.27  66.94  76.73 157.89
Frequency       1      1      1      1      1
Proportion  0.071  0.071  0.071  0.071  0.071
--------------------------------------------------------------------------------
album 
       n  missing distinct     Info     Mean      Gmd      .05      .10 
      11       12       11        1    66.15    9.592    54.06    55.36 
     .25      .50      .75      .90      .95 
   62.12    66.82    69.62    72.14    77.94 

lowest : 52.77 55.36 59.59 64.64 66.27, highest: 67.09 68.59 70.64 72.14 83.73
                                                                            
Value      52.77 55.36 59.59 64.64 66.27 66.82 67.09 68.59 70.64 72.14 83.73
Frequency      1     1     1     1     1     1     1     1     1     1     1
Proportion 0.091 0.091 0.091 0.091 0.091 0.091 0.091 0.091 0.091 0.091 0.091
--------------------------------------------------------------------------------
  • El gráfico de cajas nos muestra la disrtibución de la variable numérica en termino de sus cuantiles.

  • Los puntos aislados, fuera de las cajas y bigotes, son considerados valores extremos.

  • Estos pueden ser plausibles o no plausibles.

  • El gráfico de cajas permite identificar, rápidamente, valores extremos potencialmente no plausibles o problemáticos.

boxplot(datos$peso_final)

boxplot(datos$peso_utero)

Regla 3 con R: Haga algunas consultas (queries) de interés

Muestre el peso inicial mínimo, máximo y promedio del grupo control:

datos %>% 
  filter(tratamiento == "control") %>% 
  summarise(
    minimo_peso = min(peso_inicial), 
    maximo_peso = max(peso_inicial), 
    promedio_peso = mean(peso_inicial)
  )
  minimo_peso maximo_peso promedio_peso
1        20.4       26.59        24.198

Muestre los pesos inicial máximos, mínimo y promedio según grupo de tratamiento. También muestre el número de ratones por grupo:

datos %>% 
  group_by(tratamiento) %>% 
  summarise(
    minimo_peso = min(peso_inicial), 
    maximo_peso = max(peso_inicial), 
    promedio_peso = mean(peso_inicial), 
    n_ratones = n()
  )
# A tibble: 5 × 5
  tratamiento               minimo_peso maximo_peso promedio_peso n_ratones
  <chr>                           <dbl>       <dbl>         <dbl>     <int>
1 control                          20.4        26.6          24.2         5
2 maca                             22.7        25            23.9         5
3 maca + critro                    21.9        23.4          22.4         4
4 sham operated                    22.5        25.5          23.6         4
5 triple dosis maca + citro        18.9        27.9          24.0         5

Muestre los id_jaula con el número de ratones por jaula

datos %>% 
  group_by(id_jaula) %>% 
  summarise(n_ratones_por_jaula = n())
# A tibble: 7 × 2
  id_jaula n_ratones_por_jaula
     <dbl>               <int>
1        1                   3
2        2                   4
3        3                   3
4        5                   4
5        8                   2
6        9                   4
7       10                   3

Identifique los ID de los ratones del grupo control con una razón glucosa / colesterol > 1

datos %>% 
  filter(tratamiento == "control" & glucose / chol > 1)
  id_jaula id_raton tratamiento protocolo peso_inicial peso_final peso_utero
1        1        1     control       ovx         26.0      33.28      0.089
3        1        3     control       ovx         20.4      29.93      0.078
5        2        5     control       ovx         23.5      30.37      0.052
   chol glucose    tag prot  urea album
1 85.99  109.97 182.42 5.37 66.27 66.82
3 99.67  118.37 195.16   NA 52.32    NA
5 82.08   95.53 108.13 5.33 26.02    NA

Otra forma de hacerlo, es crear primerio la razón glucose / chol y filtrar:

datos %>% 
  mutate(ratio_gluc_chol = glucose / chol) %>% 
  filter(tratamiento == "control" & ratio_gluc_chol > 1)
  id_jaula id_raton tratamiento protocolo peso_inicial peso_final peso_utero
1        1        1     control       ovx         26.0      33.28      0.089
3        1        3     control       ovx         20.4      29.93      0.078
5        2        5     control       ovx         23.5      30.37      0.052
   chol glucose    tag prot  urea album ratio_gluc_chol
1 85.99  109.97 182.42 5.37 66.27 66.82        1.278870
3 99.67  118.37 195.16   NA 52.32    NA        1.187619
5 82.08   95.53 108.13 5.33 26.02    NA        1.163865

Análisis descriptivo

  • Luego de AID uno ya está listo para describir sus datos.

  • Hay muchas formas de describir datos, todos son combinación de medidas de resumen en texto y tablas, así como gràficos gráficos.

  • Describir las medidas que faciliten la comparación de nuestra población de estudio con otras.

Análisis descriptivo de variable numérica

  • Medias de tendencia central
    • Media
    • Mediana (es también medida de posición)
    • Moda (no es usual)
  • Medidas de posición
    • Cuantiles (en general)
    • Mediana = percentil 50 (es también medida de tendencia central)
    • Percentil 25 (p25)
    • Percentil 75 (p75)
  • Medidas de dispersión
    • Rango (máximo - mínimo)
    • Varianza / Desviación estándar
    • Rango intercuartílico (p75 - p25)
  • Simétrica
  • Asimétrica (o ‘sesgada’)
    • Positiva (A la derecha)
    • Negativa (A la izquierda)
  • Resumiendo:

Análisis descriptivo de variable numérica - recomendaciones

  • Media +/- Desviación estándar
    • Si distribución es simétrica y variabilidad es relativamente baja.
    • La distribución normal es un ejemplo de distribución simétrica.
  • Mediana (percentil 25 - percentil 75)
    • Si distribución es asimétrica o variabilidad es relativamente alta.
    • Mejor percentiles 25 y 75 en vez de rango intercuartílico (más información`de los primeros)
  • Máximo y mínimo siempre:
    • Es mejor que rango, provee más información.
    • Preferentemente en tabla principal.
    • Si problemas de espacio, usar tabla anexa.

Para la variable numérica peso inicial Se usa la función skim() y se coloca la variable de interés.

  • p0 es el valor mínimo y p100 es el valor máximo.

  • La mediana es p50.

  • mean es el promedio y sd es la desviación estándar.

# Para la variable numérica peso_inicial
datos %>% 
  skim(peso_inicial)
Data summary
Name Piped data
Number of rows 23
Number of columns 13
_______________________
Column type frequency:
numeric 1
________________________
Group variables None

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
peso_inicial 0 1 23.68 1.99 18.9 22.59 23.5 24.9 27.9 ▂▃▇▇▂

También analizamos la distribución de manera gráfica con un histograma. Se aprecia que la variable es aproximadamente simétrica:

  • Media vs mediana muy parecidas y

  • Gráfico con desviaciones ligeras de simetría.

Por lo tanto, decidimos reportar media (desviación estándar). Mímimo y máximo debería tambier reportarse (en texto o en tabla anexo).

hist(datos$peso_inicial)

Descripción del resultado (ejemplo):

El peso inicial varió entre 18.9 g y 27.9 g, con un promedio de 23.68 g (DE = 1.99 g).

Para la variable numérica triglicéridos al final del estudio, se tiene las siguientes medidas de resumen:

datos %>% 
  skim(tag)
Data summary
Name Piped data
Number of rows 23
Number of columns 13
_______________________
Column type frequency:
numeric 1
________________________
Group variables None

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
tag 0 1 153.06 52.36 90.99 108.13 141.1 190.11 282.64 ▇▃▅▁▂
  • Notar que la media y la mediana difieren en aprox. 12 mg/dl. Esto sugiere la existencia de alguna asimetría en la distribución de esta variable.

  • Veamos el gráfico:

hist(datos$tag)

  • Se aprecia que la distribución es sesgada hacia la derecha.

  • Por lo tanto, la media no sería un buen representante de toda la distribución de datos.

  • La mediana es más robusta al sesgo de la distribución y se prefiere reportarla en compañía de los percentiles 25 y 75.

Descripción del resultado (ejemplo):

El nivel de triglicéridos al final del seguimiento varió entre 90.99 mg/dL y 282.64 mg/dL, con una mediana de 141.1 mg/dL (108.13 mg/dL a 190.11 mg/dL).

Análisis descriptivo de variable categórica

  • Acompañe siempre frecuencias absolutas con relativas.

  • Cuando interprete, no reporte solo % o proporción, también indique el n, al menos entre paréntesis.

  • Frecuencia absoluta: Es el número de individuos.

  • Frecuencia relativa: Es un porcentaje (entre 0% y 100%) o una proporción (entre 0 y 1).

  • Cuidado: Reportar bien si es porcentaje (colocar siempre el %) o es una proporción (nunca colocar el %).

  • Excepción: En muestras que usan pesos muestrales, puede ser mejor solo reprotar frecuencias relativas (% o proporciones) y las frecuencias absolutas (observadas[no ponderadas] y ponderadas) dejarlas para el anexo.

  • Podemos usar la función tabyl() del paquete {janitor} para describir la distribución de frecuencias relativas y acumuladas:
datos %>% 
  tabyl(tratamiento) 
               tratamiento n   percent
                   control 5 0.2173913
                      maca 5 0.2173913
             maca + critro 4 0.1739130
             sham operated 4 0.1739130
 triple dosis maca + citro 5 0.2173913
  • La columna percent() es en realidad una proporción. Para reportar un porcentaje, se puede agregar adorn_pct_formatting():
datos %>% 
  tabyl(tratamiento) %>% 
  adorn_pct_formatting()
               tratamiento n percent
                   control 5   21.7%
                      maca 5   21.7%
             maca + critro 4   17.4%
             sham operated 4   17.4%
 triple dosis maca + citro 5   21.7%

Descripción del resultado (ejemplo):

Los grupos control, maca y triple dosis maca + citro representaron el 21.7% (n = 5) de los animales de experimentación.

  • Para la variable Glucosa categorizada tenemos la siguiente distribución de frecuencias:
datos %>% 
  tabyl(glucose_cat) %>% 
  adorn_pct_formatting()
   glucose_cat  n percent
 120-200 mg/dL 11   47.8%
  60-120 mg/dL 12   52.2%
  • Se puede mejorar la presentación usando la función gt() del paquete {gt}.
library(gt)
datos %>% 
  tabyl(glucose_cat) %>% 
  adorn_pct_formatting() %>% 
  gt()
glucose_cat n percent
120-200 mg/dL 11 47.8%
60-120 mg/dL 12 52.2%

Descripción del resultado (ejemplo):

El 52.2% (n = 12) de los animales de experimentación tuvo valores de glucosa entre 60 y 120 mg/dL.

Recomendaciones sobre reporte descriptivo según STROBE

  • Strengthening the Reporting of Observational Studies in Epidemiology (STROBE) es una guía de reporte de estudios observacionales en salud mundialmente reconocida.

  • Las revistas de alto impacto solicitan que los investigadores se adhieran a estas guías y llenen un checklist.

  • Lo que mencionamos acerca de reportar variables numéricas:
  • También debe reportarse el número de participantes con datos perdidos para cada variable de interés

Recomendaciones adicionales para mejorar un reporte descriptivo transparente según REMARK

  • Reporting Recommendations for Tumor Marker Prognostic Studies (REMARK) es una guía de reporte para estudios de marcadores pronósticos:
    • Inicialmente para cáncer.
    • Debido a su amplio alcance, se usa en casi cualquier campo (p. ej., cardiología, neurología, etc.) donde se evalúe un marcador pronóstico.
  • REMARK indica que debe reportarse la distribución de los marcadores o factores pronóstico de interés y del desenlace:
    • Biomarcador o score de predicción
    • Desenlace
  • Lamentablemente es una mala práctica no hacerlo.
    • Usen anexos si el espacio queda corto y no quieren distraer al lector del mensaje principal.
    • No hay excusa para no reportar esto.

Recomendaciones adicionales para mejorar un reporte descriptivo transparente (cont.)

  • No cree la tabla “manualmente”.

  • Genere las tablas con código:

    • Es reproducible.
    • Menos propenso a error de digitación o lapsus calamis.
    • Han habido retracciones de ensayos clínicos por errores de tipeo!!
    • Es más rápido, ahorrarás tiempo!!

Generación de tabla descriptiva reproducible

  • A menudo se la conoce como la Tabla 1.
    • Puede haber más de una, no hay reglas, solo buenos o malos criterios para presentar resultados.
  • Hay muchos paquetes: {flextable}, {gt}, etc.
  • Sugerimos: {gtsummary}: https://www.danieldsjoberg.com/gtsummary/

Tabla decriptiva reproducible con {gtsummary}

  • Permite crear tablas en formato de revistas biomédicas.

  • Función tbl_summary() para tablas descriptivas univariadas y comparativas (bivariadas)

Función tbl_summary() paso a paso

  • Seleccionar las variables que desea reportar con función select(), luego usar tbl_summary():
library(gtsummary)
datos2 %>% 
  select(age, race, married2, weight, height, e2, lh, fsh, prog) %>% 
  tbl_summary()
Characteristic N = 1061
Age, years 33.0 (29.0, 37.0)
Race
Mestiza 106 (100%)
Marital status, recat 52 (49%)
Weight, kg 59 (55, 65)
Unknown 3
Height, m
1.3 1 (1.0%)
1.4 12 (12%)
1.5 52 (50%)
1.6 28 (27%)
1.7 10 (9.7%)
Unknown 3
Estradiol 92 (59, 132)
Luteinizant Hormon 6 (3, 13)
Folicullo stimulant hormon 3.66 (2.12, 5.09)
Progesterone 10 (5, 12)
1 Median (IQR); n (%)
  • Por defecto, las variables numéricas son reportadas como mediana (percentil 25, percentil 75).

  • Asimismo, si una variable numérica tiene pocos valores, esta se muestra como categórica.

  • Uno puede personalizar esto. Veamos los siguientes pasos.

  • Indicar qué variables son numéricas con el argumento type =
datos2 %>% 
  select(age, race, married2, weight, height, e2, lh, fsh, prog) %>% 
  tbl_summary(
    type = list(height ~ "continuous")
  )
Characteristic N = 1061
Age, years 33.0 (29.0, 37.0)
Race
Mestiza 106 (100%)
Marital status, recat 52 (49%)
Weight, kg 59 (55, 65)
Unknown 3
Height, m 1.50 (1.50, 1.60)
Unknown 3
Estradiol 92 (59, 132)
Luteinizant Hormon 6 (3, 13)
Folicullo stimulant hormon 3.66 (2.12, 5.09)
Progesterone 10 (5, 12)
1 Median (IQR); n (%)
  • Notar que ahora height es considerada una variable numérica y se reporta como mediana con sus respectivos percentiles.
  • ¿Qué pasa si queremos reportar media (desviación estándar) para las variables simétricas height y weight, pero mantener la mediana (percentiles) para las variables e2, lh, fsh, y prog.

  • Se puede configurar esto con el argumento statistic =

datos2 %>% 
  select(age, race, married2, weight, height, e2, lh, fsh, prog) %>% 
  tbl_summary(
    type = list(height ~ "continuous"), 
    statistic = list(c(age, weight, height) ~ "{mean} ({sd})", c(e2, lh, fsh, prog) ~ "{median} ({p25}, {p75})")
  )
Characteristic N = 1061
Age, years 32.8 (5.5)
Race
Mestiza 106 (100%)
Marital status, recat 52 (49%)
Weight, kg 61 (8)
Unknown 3
Height, m 1.53 (0.08)
Unknown 3
Estradiol 92 (59, 132)
Luteinizant Hormon 6 (3, 13)
Folicullo stimulant hormon 3.66 (2.12, 5.09)
Progesterone 10 (5, 12)
1 Mean (SD); n (%); Median (IQR)
datos2 %>% 
  select(age, race, married2, weight, height, e2, lh, fsh, prog) %>% 
  tbl_summary(
    type = list(height ~ "continuous"), 
    statistic = list(c(age, weight, height, e2, lh, fsh, prog) ~ "{min} - {max}")
  )
Characteristic N = 1061
Age, years 20.0 - 41.0
Race
Mestiza 106 (100%)
Marital status, recat 52 (49%)
Weight, kg 48 - 92
Unknown 3
Height, m 1.30 - 1.70
Unknown 3
Estradiol 21 - 404
Luteinizant Hormon 1 - 93
Folicullo stimulant hormon 0.82 - 21.18
Progesterone 0 - 28
1 Range; n (%)
  • Se puede descargar la tabla en formato MS. Word para reporte reproducible.

  • Primero se guarda como un objeto de R:

datos2 %>% 
  select(age, race, married2, weight, height, e2, lh, fsh, prog) %>% 
  tbl_summary(
    type = list(height ~ "continuous"), 
    statistic = list(c(age, weight, height) ~ "{mean} ({sd})", c(e2, lh, fsh, prog) ~ "{median} ({p25}, {p75})")
  ) -> tabla1 

tabla1
Characteristic N = 1061
Age, years 32.8 (5.5)
Race
Mestiza 106 (100%)
Marital status, recat 52 (49%)
Weight, kg 61 (8)
Unknown 3
Height, m 1.53 (0.08)
Unknown 3
Estradiol 92 (59, 132)
Luteinizant Hormon 6 (3, 13)
Folicullo stimulant hormon 3.66 (2.12, 5.09)
Progesterone 10 (5, 12)
1 Mean (SD); n (%); Median (IQR)
  • Luego, al objeto se lo guarda como un archivo de MS Word. Para esto, se usa la función as_flex_table() del paquete {gtsummary} y la función save_as_docx() del paquete {flextable}:
# install.packages(flextable)
library(flextable)
tabla1 %>% 
  as_flex_table() %>% 
  save_as_docx(path = "Tabla1.docx")
  • El MS Word aparecerá en la carpeta del proyecto:

  • Y la tabla en Word lucirá así:






Preguntas?





Muchas gracias!